﻿Imports System.Runtime.InteropServices

Public NotInheritable Class TaskbarInfo

    <DllImport("user32.dll", SetLastError:=True)> _
    Private Shared Function FindWindow(ByVal lpClassName As String, ByVal lpWindowName As String) As IntPtr
    End Function

    <DllImport("shell32.dll", SetLastError:=True)> _
    Public Shared Function SHAppBarMessage(ByVal dwMessage As ABM, <[In]()> ByRef pData As TASKBARDATA) As IntPtr
    End Function

    Enum ABM As UInteger
        [New] = &H0
        Remove = &H1
        QueryPos = &H2
        SetPos = &H3
        GetState = &H4
        GetTaskbarPos = &H5
        Activate = &H6
        GetAutoHideBar = &H7
        SetAutoHideBar = &H8
        WindowPosChanged = &H9
        SetState = &HA
    End Enum

    Enum Position As UInteger
        Left = 0
        Top = 1
        Right = 2
        Bottom = 3
    End Enum

    <StructLayout(LayoutKind.Sequential)> _
    Structure TASKBARDATA
        Public cbSize As UInteger
        Public hWnd As IntPtr
        Public uCallbackMessage As UInteger
        Public uEdge As Position
        Public rc As RECT
        Public lParam As Integer
    End Structure

    <StructLayout(LayoutKind.Sequential)> _
    Structure RECT
        Public left As Integer
        Public top As Integer
        Public right As Integer
        Public bottom As Integer
    End Structure

    Public Shared Function GetTaskbarInfo() As TASKBARDATA
        Dim taskbarHandle As IntPtr = FindWindow("Shell_TrayWnd", Nothing)

        Dim data As New TASKBARDATA()
        data.cbSize = CUInt(Marshal.SizeOf(GetType(TASKBARDATA)))
        data.hWnd = taskbarHandle
        Dim result As IntPtr = SHAppBarMessage(ABM.GetTaskbarPos, data)

        If result = IntPtr.Zero Then
            Throw New InvalidOperationException()
        End If

        Return data
    End Function

End Class